package cn.tom.config.smsFilter;

import cn.tom.entity.XUser;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

public class SmsCodeAuthenticationProvider implements AuthenticationProvider {
    private final RedisTemplate redisTemplate;
    private final UserDetailsService userDetailsService;


    public SmsCodeAuthenticationProvider(RedisTemplate redisTemplate,UserDetailsService userDetailsService) {
        this.redisTemplate = redisTemplate;
        this.userDetailsService = userDetailsService;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        SmsCodeAuthenticationToken authenticationToken =(SmsCodeAuthenticationToken) authentication;
        String principal =(String) authenticationToken.getPrincipal();
        checkSmsCode(principal);
        XUser user =(XUser) userDetailsService.loadUserByUsername(principal);

        SmsCodeAuthenticationToken authenticationResult = new SmsCodeAuthenticationToken(user,user.getAuthorities());
        authenticationResult.setDetails(authenticationToken.getDetails());
        // 从原始SmsCodeAuthenticationToken中获取详细信息（可能包含IP地址、会话ID等），并将其设置到新的验证令牌上。
        return authenticationResult;
    }

    private void checkSmsCode(String principal){
        ServletRequestAttributes req = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request ;
        if (req != null){
            request = req.getRequest();
        }else {
            throw new NullPointerException(" 空指针异常 ");
        }
        String code1 = request.getParameter("code");
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        String code = ops.get(principal);
        if (code == null){
            throw new BeanCreationException("未检测到验证码");
        }
        if (!code.equals(code1)){
            throw new BadCredentialsException("验证码输入有误");
        }
       redisTemplate.delete(principal);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
